//
// Created by YE on 2024/2/13.
//

#ifndef MATINTERPRETER_HASH_H
#define MATINTERPRETER_HASH_H

#include "ych_object.h"

#define HASH_SIZE 32
#define HASH_TABLE_LOAD_FACTOR_THRESHOLD 0.75

typedef struct FuncInfo {
    Uint func_p;
    int func_params;
    int var_nums;
} FuncInfo;


typedef struct IntHashNode {
    Int key;
    Uint value;
    int hash;
    struct IntHashNode *next;
} IntHashNode;
typedef struct FloatHashNode {
    Float key;
    Uint value;
    int hash;
    struct FloatHashNode *next;
} FloatHashNode;
typedef struct StringHashNode {
    char *key;
    Uint value;
    int hash;
    struct StringHashNode *next;
} StringHashNode;
typedef struct FuncHashNode {
    char *key;
    FuncInfo value;
    int hash;
    struct FuncHashNode *next;
} FuncHashNode;

typedef struct IntHashMap {
    IntHashNode **table;
    int size;
    int capacity;
    int threshold;
} IntHashMap;

typedef struct FloatHashMap {
    FloatHashNode **table;
    int size;
    int capacity;
    int threshold;
} FloatHashMap;

typedef struct StringHashMap {
    StringHashNode **table;
    int size;
    int capacity;
    int threshold;
} StringHashMap;

typedef struct FuncHashMap {
    FuncHashNode **table;
    int size;
    int capacity;
    int threshold;
} FuncHashMap;


typedef struct VarHashNode {
    char *key;
    Uint value;
    int hash;
    struct VarHashNode *next;
} VarHashNode;
typedef struct VarHashMap {
    VarHashNode **table;
    int size;
    int capacity;
    int threshold;
} VarHashMap;
void initVarHashMap(VarHashMap *hash_map);
void insertVarHashMap(VarHashMap *hash_map, char *string, Uint p);
int lookUpVarHashMap(VarHashMap *hash_map, char *string, VarHashNode **node_p);
void deleteKeyVarHashMap(VarHashMap *hash_map, char *string);
void freeVarHashMap(VarHashMap *hash_map);
void clearVarHashMap(VarHashMap *hash_map);
void extendVarHashMap(VarHashMap *hash_map);



void initIntHashMap(IntHashMap *hash_map);

void insertIntHashMap(IntHashMap *hash_map, Int i, Uint p);

int lookUpIntHashMap(IntHashMap *hash_map, Int i, IntHashNode **node_p);

void freeIntHashMap(IntHashMap *hash_map);

void extendIntHashMap(IntHashMap *hash_map);

void initFloatHashMap(FloatHashMap *hash_map);

void insertFloatHashMap(FloatHashMap *hash_map, Float f, Uint p);

int lookUpFloatHashMap(FloatHashMap *hash_map, Float f, FloatHashNode **node_p);

void freeFloatHashMap(FloatHashMap *hash_map);

void extendFloatHashMap(FloatHashMap *hash_map);

void initStringHashMap(StringHashMap *hash_map);

void insertStringHashMap(StringHashMap *hash_map, char *string, Uint p);

int lookUpStringHashMap(StringHashMap *hash_map, char *string, StringHashNode **node_p);

void freeStringHashMap(StringHashMap *hash_map);

void extendStringHashMap(StringHashMap *hash_map);

void initFuncHashMap(FuncHashMap *hash_map);

FuncHashNode *insertFuncHashMap(FuncHashMap *hash_map, char *string, int func_params, int var_nums, Uint func_p);

int lookUpFuncHashMap(FuncHashMap *hash_map, char *string, FuncHashNode **node_p);
void deleteKeyFuncHashMap(FuncHashMap *hash_map, char *string);
void freeFuncHashMap(FuncHashMap *hash_map);

void extendFuncHashMap(FuncHashMap *hash_map);

int hashString(char *string);

int hashInt(Int i);

int hashFloat(Float f);

#endif //MATINTERPRETER_HASH_H
